package com.iims.market.service.impl;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.iims.common.constant.DeleteFlag;
import com.iims.common.constant.UserConstants;
import com.iims.common.core.domain.TreeSelect;
import com.iims.common.exception.CustomException;
import com.iims.market.domain.ContractType;
import com.iims.market.domain.entity.CtraTreeSelect;
import com.iims.market.mapper.ContractTypeMapper;
import com.iims.market.service.IContractTypeService;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 产品类型服务
 *
 * @author fanpei
 * @date 2021/6/11 14:52
 */
@Service
public class ContractTypeServiceImpl extends ServiceImpl<ContractTypeMapper, ContractType> implements IContractTypeService {

    @Override
    public List<ContractType> selectContractTypeList(ContractType ctratype) {
        return baseMapper.selectList(new LambdaQueryWrapper<ContractType>()
                .like(StrUtil.isNotBlank(ctratype.getCtraTypeName()), ContractType::getCtraTypeName, ctratype.getCtraTypeName())
                .eq(ContractType::getDelFlag, DeleteFlag.未删除.getVal())
        );
    }

    @Override
    public ContractType selectOne(Long ctraTypeId) {
        return baseMapper.selectById(ctraTypeId);
    }

    @Override
    public String checkContractTypeNameUnique(ContractType contractType) {
        Long typeId = Validator.isNull(contractType.getCtraTypeId()) ? -1L : contractType.getCtraTypeId();
        ContractType info = getOne(new LambdaQueryWrapper<ContractType>()
                .eq(ContractType::getCtraTypeName, contractType.getCtraTypeName())
                .eq(ContractType::getDelFlag, DeleteFlag.未删除.getVal())
                .last("limit 1"));
        if (Validator.isNotNull(info) && info.getCtraTypeId().longValue() != typeId.longValue()) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public int insertContractType(ContractType ctratype) {
        ContractType info = getById(ctratype.getParentId());
        // 如果父节点不为正常状态,则不允许新增子节点
        if (Validator.isNull(info)) {
            ctratype.setAncestors(ctratype.getParentId().toString());
        } else {
            if (DeleteFlag.已删除.getVal().equals(info.getDelFlag())) {
                throw new CustomException("类型已删除，不允许新增");
            }
            ctratype.setAncestors(info.getAncestors() + "," + ctratype.getParentId());
        }
        return baseMapper.insert(ctratype);
    }

    @Override
    public int updateContractType(ContractType ctratype) {
        return baseMapper.updateById(ctratype);
    }

    @Override
    public int deleteContractTypeById(Long ctraTypeId) {
        return baseMapper.deleteById(ctraTypeId);
    }

    @Override
    public int selectChildrenCount(Long ctraTypeId) {
        return baseMapper.selectCount(new LambdaQueryWrapper<ContractType>().eq(ContractType::getParentId, ctraTypeId));
    }

    @Override
    public List<ContractType> buildCtraTypeTreeList(List<ContractType> types) {
        return buildMenuTree(types);
    }


    @Override
    public List<CtraTreeSelect> buildCtraTypeTreeSelect(List<ContractType> types) {
        List<ContractType> contrTrees = buildMenuTree(types);
        return contrTrees.stream().map(CtraTreeSelect::new).collect(Collectors.toList());
    }

    /**
     * 构建前端所需要树结构
     *
     * @param ctypes 菜单列表
     * @return 树结构列表
     */
    public List<ContractType> buildMenuTree(List<ContractType> ctypes) {
        List<ContractType> returnList = new ArrayList<ContractType>();
        List<Integer> tempList = new ArrayList<>(ctypes.size());
        for (ContractType ctype : ctypes) {
            tempList.add(ctype.getCtraTypeId());
        }
        for (Iterator<ContractType> iterator = ctypes.iterator(); iterator.hasNext(); ) {
            ContractType type = (ContractType) iterator.next();
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(type.getParentId())) {
                recursionFn(ctypes, type);
                returnList.add(type);
            }
        }
        if (returnList.isEmpty()) {
            returnList = ctypes;
        }
        return returnList;
    }

    /**
     * 递归列表
     *
     * @param list
     * @param t
     */
    private void recursionFn(List<ContractType> list, ContractType t) {
        // 得到子节点列表
        List<ContractType> childList = getChildList(list, t);
        t.setChildren(childList);
        for (ContractType tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<ContractType> getChildList(List<ContractType> list, ContractType t) {
        List<ContractType> tlist = new ArrayList<ContractType>();
        Iterator<ContractType> it = list.iterator();
        while (it.hasNext()) {
            ContractType n = it.next();
            if (n.getParentId().intValue() == t.getCtraTypeId().intValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<ContractType> list, ContractType t) {
        return getChildList(list, t).size() > 0 ? true : false;
    }
}
